namespace SimpleWebServices.Configuration
{
    using System;
    using System.Collections.ObjectModel;
    using System.Configuration;
    using System.Xml;
    using Xunit;

    public sealed class SubmissionConfigurationFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<SubmissionConfiguration>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .Implements<IConfigurationSectionHandler>()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new SubmissionConfiguration());
        }

        [Fact]
        public void op_Clear()
        {
            SubmissionConfiguration.Clear();

            try
            {
                Assert.Empty(SubmissionConfiguration.Settings());

                SubmissionConfiguration.Settings().Add("<handler />".Deserialize<SubmissionHandlerSetting>());

                Assert.NotEmpty(SubmissionConfiguration.Settings());
            }
            finally
            {
                SubmissionConfiguration.Reset();
            }
        }

        [Fact]
        public void op_Handler_string()
        {
            SubmissionConfiguration.Clear();

            try
            {
                Assert.Empty(SubmissionConfiguration.Settings());

                SubmissionConfiguration.Settings().Add("<handler name='test' />".Deserialize<SubmissionHandlerSetting>());

                Assert.NotNull(SubmissionConfiguration.Handler("test"));
            }
            finally
            {
                SubmissionConfiguration.Reset();
            }
        }

        [Fact]
        public void op_Handler_stringEmpty()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => SubmissionConfiguration.Handler(string.Empty));
        }

        [Fact]
        public void op_Handler_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => SubmissionConfiguration.Handler(null as string));
        }

        [Fact]
        public void op_Reset()
        {
            int expected = SubmissionConfiguration.Settings().Count;

            SubmissionConfiguration.Clear();

            Assert.Empty(SubmissionConfiguration.Settings());

            SubmissionConfiguration.Reset();

            int actual = SubmissionConfiguration.Settings().Count;

            Assert.Equal<int>(expected, actual);
        }
        
        [Fact]
        public void op_Settings()
        {
            Assert.NotNull(SubmissionConfiguration.Settings());
        }

        [Fact]
        public void op_Settings_string()
        {
            Assert.NotNull(SubmissionConfiguration.Settings("simplewebservices/submission"));
        }

        [Fact]
        public void op_Create_object_object_XmlNodeNull()
        {
            Collection<SubmissionHandlerSetting> actual = new SubmissionConfiguration().Create(null, null, null as XmlNode) as Collection<SubmissionHandlerSetting>;

            Assert.Empty(actual);
        }

        [Fact]
        public void op_Create_object_object_XmlNodeEmpty()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml("<submission />");

            Collection<SubmissionHandlerSetting> actual = new SubmissionConfiguration().Create(null, null, xml.DocumentElement) as Collection<SubmissionHandlerSetting>;

            Assert.Empty(actual);
        }

        [Fact]
        public void op_Create_object_object_XmlNode()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(
                "<submission>" +
                    "<handler name='first'>" +
                        "<processor id='component' />" +
                    "</handler>" +
                "</submission>");

            Collection<SubmissionHandlerSetting> actual = new SubmissionConfiguration().Create(null, null, xml.DocumentElement) as Collection<SubmissionHandlerSetting>;

            Assert.NotEmpty(actual);

            Assert.Equal<string>("first", actual[0].Name);
            Assert.Equal<string>("component", actual[0].Processors[0].Id);
        }

        [Fact]
        public void op_Create_object_object_XmlNodeInvalid()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml("<bad-name/>");

            Collection<SubmissionHandlerSetting> actual = new SubmissionConfiguration().Create(null, null, xml.DocumentElement) as Collection<SubmissionHandlerSetting>;

            Assert.Empty(actual);
        }
    }
}